package sliceformUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import pluginUtils.Plane;
import pluginUtils.Pos3D;

/** Une ligne, c'est une suite de segments
 * coplanaires : on memorise aussi le plan de coupe
 * il faudrait voir s'ils sont consecutifs...
 * 
 * @author francesco
 *
 **/
public class Ligne extends  Encombrant implements Iterable<Segment> ,Rotable<Ligne>{
	
	protected Set<Pos3D> lesSommets=new HashSet<Pos3D>(); 
	protected ArrayList<Segment> lesSegments=new ArrayList<Segment>(); 
	protected Plane lePlan; 
	
	
	public boolean add(Segment t){
		//lesSegments.add(t); 
		
		if(t.getMinX()<minX)minX=t.getMinX(); 
		if(t.getMaxX()>maxX)maxX=t.getMaxX(); 
		
		if(t.getMinY()<minY)minY=t.getMinY(); 
		if(t.getMaxY()>maxY)maxY=t.getMaxY(); 
		
		if(t.getMinZ()<minZ)minZ=t.getMinZ(); 
		if(t.getMaxZ()>maxZ)maxZ=t.getMaxZ(); 
		
		xwide=maxX-minX;
		ywide=maxY-minY;
		zwide=maxZ-minZ; 
		
		lesSommets.add(t.getOne()); 
		lesSommets.add(t.getTwo()); 
		
		return lesSegments.add(t); 
	}



	@Override
	public Iterator<Segment> iterator() {
		return lesSegments.iterator(); 
	}



	public Plane getLePlan() {
		return lePlan;
	}



	public Ligne(Plane lePlan) {
		super();
		this.lePlan = lePlan;
	}
	
	/** Verifie que tous les points appartiennent au plan de reference **/
	public void verify(){
		for(Pos3D t:lesSommets){
			System.out.println(lePlan.relative(t)); 
		}
	}



	@Override
	// Ne marche que pour les rotations ramenant dans un plan permediculaire a OX
	public Ligne rotate(CoupleDAngles cda) {
		// Premierement, modifier le plan de base
		Pos3D temoin; 
		double dist; 
		if(lePlan.getD()==0) dist=0; 
		if(lePlan.getA()!=0){
			temoin=new Pos3D(-lePlan.getA()/lePlan.getD(),0,0); 
			Pos3D taux=temoin.rotate(cda); 
			dist=taux.getX(); 
		}
		else 
			if(lePlan.getB()!=0){
				temoin=new Pos3D(0,-lePlan.getB()/lePlan.getD(),0); 
				Pos3D taux=temoin.rotate(cda); 
				dist=taux.getX(); 
			}
			else{ // getC() est forcement different de 0
				temoin=new Pos3D(0,0,-lePlan.getC()/lePlan.getD()); 
				Pos3D taux=temoin.rotate(cda); 
				dist=taux.getX(); 
			}
		Plane planCourant=new Plane(1,0,0,-dist); 
		Ligne nouvelle=new Ligne(planCourant); 
		for(Segment s:this.lesSegments)
			nouvelle.add(s.rotate(cda));
		return nouvelle; 
	}



	@Override
	// Ne marche que pour les plans perpendiculaires a OX
	public Ligne rotateInverse(CoupleDAngles cda) {
		Pos3D t1,t2,t3;
		t1=new Pos3D(lePlan.getD(),0,0); 
		t2=new Pos3D(lePlan.getD(),1,0); 
		t3=new Pos3D(lePlan.getD(),0,1);
		t1=t1.rotateInverse(cda); 
		t2=t2.rotateInverse(cda); 
		t3=t3.rotateInverse(cda); 
		
		Plane planCourant=new Plane(t1,t2,t3); 
		Ligne nouvelle=new Ligne(planCourant); 
		for(Segment s:this.lesSegments)
			nouvelle.add(s.rotateInverse(cda));
		return nouvelle; 
		
	}
	

}
